home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / d86v311b.arc / BIOS.8 < prev    next >
Text File  |  1987-11-23  |  37KB  |  901 lines

  1. ;---------------
  2. ;   BIOS module for the D86 debugger
  3. ;---------------
  4.  
  5. ; Copyright (C)1987 Eric Isaacson.  All rights reserved.  Permission to
  6. ; copy and use this module is granted ONLY for machines registered for both
  7. ; the A86 assembler and the D86 debugger.
  8.  
  9. ; Current support: IBM-PC, Wang PC, TI-PC, Sanyo 555, and Tandy 2000
  10.  
  11. ; This module defines the BIOS interface for my D86 debugger.  I am publishing
  12. ; it to assist those who wish to assist me in implementing D86 on machines not
  13. ; BIOS-compatible with the IBM-PC.  To support a non-standard BIOS, we must
  14. ; provide new keyboard codes, new action routines, and several other data
  15. ; quantities.  The scenario for this is as follows:
  16.  
  17. ; First, the debugger calls the procedure SET_MACHINE.    This procedure must
  18. ; detect what kind of machine it is running on, and set two variables:
  19. ;
  20. ;  * SUBDIR_CHAR, a byte giving the character that indicates a subdirectory for
  21. ;    an MS-DOS path name on your computer.  On an IBM-PC this is a backslash \
  22. ;    (e.g. a file name can be \usr\eric\foo.com); on a Wang this is an ordinary
  23. ;    backslash (e.g. the same file is /usr/eric/foo.com).
  24. ;
  25. ;  * BIOS_INIT, a pointer to a procedure that does BIOS-specific
  26. ;    initializations.
  27. ;
  28. ; Next, after performing some internal initializations, the debugger calls the
  29. ; BIOS_INIT routine.  That routine must do three things:
  30. ;
  31. ; 1. The routine must point SI to a special data structure (which I'll
  32. ;    describe shortly), then call the routine NEW_KEYS, to propagate the
  33. ;    items in the structure to the necessary places throughout the debugger.
  34. ;
  35. ; 2. The routine must perform any initializations necessary for this BIOS.
  36. ;    For example, WANG_CONFIG locates and stores the port number for hardware
  37. ;    that enables video access on the Wang.
  38. ;
  39. ; 3. The routine must decide if the debugger is running on the same screen as
  40. ;    the user program.  If it is, it must move the user's cursor to the lower
  41. ;    left corner of the screen.
  42. ;
  43. ; The structure fed to NEW_KEYS contains all the data necessary for ongoing
  44. ; debugger execution under the new BIOS.  See the structure WANG_KEYS for a
  45. ; prototype.  The structure consists of the following:
  46. ;
  47. ;  * a byte giving the keyboard code for the debugger's HELP key.
  48. ;
  49. ;  * a byte declaring the difference between your BIOS's key codes for
  50. ;    function keys, and the IBM BIOS's key codes.  Your BIOS_KEY must return
  51. ;    consecutive values for the function keys F1 through F10.  You should
  52. ;    declare this byte to be X - FUNC, where X is one less than the code
  53. ;    returned by the F1 key.  For example, since the Wang F1 key returns hex
  54. ;    080, the byte is declared 07F - FUNC.
  55.  
  56. ;  * a number of bytes giving code values for all the other control keys
  57. ;    used by the debugger.  This list will be expanding with new versions;
  58. ;    see WANG_KEYS for the current version's list.  You should precede the list
  59. ;    with the L1 label, and follow it with the declaration N_CONTROL_KEYS EQU
  60. ;    $-L1, exactly as shown.  Don't change the name N_CONTROL_KEYS; the
  61. ;    redeclaration of the same name insures that you've gotten the right number
  62. ;    of codes into the table.
  63. ;
  64. ;  * a word pointing to a message string with the name of the help-key.  If your
  65. ;    keyboard has a key labelled HELP, use the name HELP_HELP as in WANG_KEYS.
  66. ;    If there is another key nonexistent on the IBM-PC (e.g. F11), then put
  67. ;    a new name (e.g. F11_HELP) following DW; I'll supply the definition for
  68. ;    the new name.  If there is no extra key and no HELP key, use Alt-F10 as
  69. ;    on the IBM-PC, and declare DW ALTF10_HELP here.
  70. ;
  71. ;  * the label L2: to be used to verify the number of following bytes.
  72. ;
  73. ;  * pointers to your BIOS's versions of the procedures VID_COPY, VID_ATTR,
  74. ;    VID_FIX, BIOS_BELL, and BIOS_KEY, described shortly. Substitute the name
  75. ;    of your machine for VID and BIOS in the generic names; e.g. the WANG_KEYS
  76. ;    structure has WANG_COPY, WANG_ATTR, WANG_BELL, and WANG_KEY.
  77. ;
  78. ;  * a word giving the segment register value for video memory on your machine.
  79. ;    The debugger will supply this value in the ES register when it calls
  80. ;    VID_COPY and VID_ATTR.  That is all the debugger does with it; so this
  81. ;    value can really be anything that the BIOS's versions of VID_COPY and
  82. ;    VID_ATTR want.
  83. ;
  84. ;  * a byte giving the attribute value for normal video.  This attribute will
  85. ;    be in effect for the entire debugger screen, except for the location of
  86. ;    the debugger's cursor.
  87. ;
  88. ;  * a byte giving the attribute value for reverse video.  This attribute will
  89. ;    be used to mark the debugger cursor.
  90. ;
  91. ;  * the declaration N_BIOS_CALLS EQU ($-L2)/2  Again, don't change the name;
  92. ;    the redeclaration of the name insures you didn't leave anything out.
  93. ;
  94. ; This completes the description of the structure fed to NEW_KEYS.  After
  95. ; BIOS_INIT is called, the debugger will keep calling 7 action routines to
  96. ; perform its interactive I/O.    The routines must perform actions as
  97. ; follows:
  98.  
  99. ; VID_COPY copies CL bytes of characters from DS:SI to the video memory whose
  100. ;   location is given by ES:DI.  The characters should have the attribute
  101. ;   NORM_ATTR, which the caller will place into AH for VID_COPY's convenience.
  102. ;   VID_COPY must place the character byte and the attribute byte into each
  103. ;   output video word.    VID_COPY must return with BL preserved, the high byte
  104. ;   of SI preserved (it will be if you leave SI pointing beyond the bytes
  105. ;   copied), and DI advanced beyond the video memory just output.  The caller
  106. ;   assumes that video memory can be found at the value of VIDEO_SEG set by
  107. ;   BIOS_INIT, starting at offset 0, and proceeding consecutively, one 16-bit
  108. ;   memory word for every character.  The caller will set CH=0 for its first
  109. ;   call, so that VID_COPY can use CX as the count; but if it does, it must
  110. ;   return CH=0 for subsequent calls.
  111.  
  112. ; VID_ATTR places the attribute byte AL into the video word whose location is
  113. ;   given by ES:DI.  The character byte of the video word must not be disturbed.
  114.  
  115. ; VID_FIX restores a video screen that might have been clobbered by programs
  116. ;   external to the debugger.  If VID_COPY copies all characters to video memory
  117. ;   every time, then VID_FIX should RET without doing anything.  If, however,
  118. ;   VID_COPY tries to keep track of which characters are already on the screen,
  119. ;   and suppress video output for those that are, then VID_FIX should disable
  120. ;   the suppression feature, call the debugger's routine REFRESH to update the
  121. ;   whole screen, then re-enable the suppression feature.
  122.  
  123. ; BIOS_BELL rings the bell.  NOTE that it is not acceptible for BIOS_BELL to
  124. ;   use the MS-DOS write routine to send a bell control-code to standard output;
  125. ;   if it did, then the debugger couldn't debug programs that have redirected
  126. ;   their standard output-- the bell code would go to the user program's output
  127. ;   file, and not be translated into a beep.
  128.  
  129. ; BIOS_KEY returns in AL a code for a single keystroke.  The code should be
  130. ;   compatible with the values placed into the debugger's function tables by
  131. ;   BIOS_INIT.    If there is no keystroke available, BIOS_KEY should wait until
  132. ;   there is one.  BIOS_KEY should return on each individual key, and not wait
  133. ;   for any line-editing to take place.
  134.  
  135. ; BIOS_SAVE saves whatever there is about the user program's BIOS state that
  136. ;   might be clobbered by the debugger.  Currently, the only such thing is
  137. ;   the user's cursor position on the Sanyo.  So on all machines but the Sanyo,
  138. ;   this is a "do-nothing" routine.
  139.  
  140. ; BIOS_RESTORE restores the BIOS state saved by BIOS_SAVE.  Again, this routine
  141. ;   does nothing except on the Sanyo, on which it restores the user cursor
  142. ;   position, clobbered because D86 must use BIOS calls to write to the Sanyo
  143. ;   screen.
  144.  
  145. ; SET_MACHINE determines what kind of machine we are running on, and sets
  146. ;   the variables SUBDIR_CHAR and BIOS_INIT accordingly.
  147.  
  148. TI_MSG_PTR  DD    0F400:0A022
  149.  
  150. TI_MSG:
  151.             DB 'Texas I'
  152. TI_MSG_LEN  EQU $-TI_MSG
  153.  
  154. TANDY_MSG1_PTR DD 0FC00:0002F      ; There are two BIOS versions for
  155. TANDY_MSG2_PTR EQU 0032       ; the Tandy 2000 slightly different
  156.  
  157. TANDY_MSG:
  158.             DB  'Tandy'
  159. TANDY_MSG_LEN EQU $-TANDY_MSG
  160.  
  161. L2:            ; BH is not 1
  162.   ADD BH,2        ; was BH 0FF?
  163.   JNZ RET        ; return if not -- we are on an IBM-PC
  164.   MOV ES,AX,0FFFF    ; it was-- address the end of ROM
  165.   ES CMP AX,[6]         ; are there FFFF's beyond the boot-JMP?
  166.   MOV AX,SANYO_CONFIG    ; load Sanyo address, in case there were
  167.   JE >L1             ; jump if there were-- it is a Sanyo
  168.   RET
  169.  
  170. SET_MACHINE:
  171.   CMP DH,DH             ; set Z so a JMP can be patched into NOPS
  172.   NOP                   ; you could patch a JMP to force a specific interface
  173.   NOP
  174.   LES DI,TI_MSG_PTR    ; point to the identifying message in the TI-PC ROM
  175.   MOV SI,TI_MSG     ; point to our copy of that message
  176.   MOV CX,TI_MSG_LEN    ; load the number of bytes that we have
  177.   REPE CMPSB        ; is the message there in ROM?
  178.   MOV AX,TIPC_CONFIG    ; load pointer to TI-PC's BIOS_INIT in case it is
  179.   JE >L1        ; jump if it is, to store the pointer
  180.   LES DI,TANDY_MSG1_PTR ; point to the identifying message in the T2K ROM
  181.   MOV SI,TANDY_MSG    ; point to Tandy identifying message
  182.   MOV CX,TANDY_MSG_LEN    ; length of message to compare
  183.   PUSH SI,CX        ; save pointer+count in case we have to try other place
  184.   REPE CMPSB        ; check for match in ROM header
  185.   POP CX,SI        ; restore count and pointer
  186.   MOV AX,TANDY_CONFIG    ; set pointer to Tandy 2000 BIOS_INIT
  187.   JE >L1        ; jump and store pointer if we found it
  188.   MOV DI,TANDY_MSG2_PTR ; point to second version message in the T2K ROM
  189.   REPE CMPSB        ; check for match in ROM header
  190.   JE >L1        ; jump and store pointer if we found it
  191.   MOV AH,030        ; MS-DOS function number for VERSION
  192.   INT 33        ; fetch the version; we want the machine code BH
  193.   DEC BH        ; if BH was 1 we are on a Wang PC
  194.   JNZ L2        ; variables already set if we are on an IBM-PC
  195.   MOV SUBDIR_CHAR,'/'   ; subdirectory character on a Wang is /
  196.   MOV AX,WANG_CONFIG    ; action routine for TI-PC is TIPC_CONFIG
  197. L1:
  198.   MOV BIOS_INIT,AX    ; store the action routine for this machine
  199.   RET
  200.  
  201.  
  202. ; IBM_CONFIG is the BIOS_INIT routine for the IBM-PC.  Since its NEW_KEY
  203. ;   values are the defaults, we do not need to call NEW_KEY.
  204.  
  205. IBM_CONFIG:
  206.   MOV AH,15          ; function number for GET_VIDEO_MODE
  207.   INT 16          ; call the BIOS to get the mode
  208.   CMP AL,7          ; are we in monochrome mode?
  209.   MOV AX,0B000          ; load monochrome map location in case yes
  210.   IF B MOV AH,0B8     ; if not then load color map location
  211.   MOV BL,V_FLAG       ; load the setting of the -V switch
  212.   XOR AH,BL          ; switch intefaces if we saw a -V in invocation
  213.   CS MOV VIDEO_SEG,AX ; store the location of physical video
  214.   TEST AH,8              ; are we on a CGA video board?
  215.   JZ >L1              ; skip if not
  216.   CS MOV VID_COPY,COLOR_COPY  ; we are: change the video-copy routine
  217.   CS MOV BIOS_RESTORE,COLOR_RESTORE
  218.   CS MOV REV_ATTR,0F0          ; change the reverse-video to blinking
  219. L1:
  220.   TEST BL          ; are we the same screen as the user program?
  221.   JNZ RET          ; return if we are not-- no need to move cursor
  222. SET_IBM_LOW_LEFT:
  223.   MOV BH,0          ; page number is zero
  224.   MOV DX,24 BY 0      ; we will move the cursor to row 24, column 0
  225. SET_IBM_CURSOR:
  226.   MOV AH,2          ; video BIOS function number for SET CURSOR POSITION
  227.   INT 16          ; call the BIOS to put user cursor in lower left corner
  228.   RET
  229.  
  230.  
  231. ; IBM_FIX performs a fixup of a trashed screen on an IBM machine.
  232.  
  233. ; COLOR_RESTORE checks to see if the debugger screen has been trashed.    If it
  234. ;   has, we restore the screen.
  235.  
  236. COLOR_RESTORE:
  237.   PUSH DS
  238.   MOV DS,AX,0B800
  239.   MOV DX,03DA        ; load the port number for reading the video status
  240. L2:            ; loop here to wait for vertical retrace
  241.   IN AL,DX        ; input the status
  242.   TEST AL,1        ; mask the retrace bit
  243.   JZ L2         ; loop if we are not in vertical retrace
  244.   CMP B[2400],'A'
  245.   POP DS
  246.   JE RET
  247. IBM_FIX:
  248.   CS PUSH VID_COPY         ; save the old VID_COPY value
  249.   CS MOV VID_COPY,MONO_COPY  ; coerce it to MONO_COPY, to blindly copy all
  250.   CALL REFRESH             ; refresh the screen; let the snow scatter!
  251.   CS POP VID_COPY         ; restore the old VID_COPY value
  252. IBM_SAVE:
  253. IBM_RESTORE:
  254.   RET
  255.  
  256.  
  257. ; MONO_COPY is the VID_COPY routine for an IBM monochrome video board.    The
  258. ;   characters occupy the lower byte of the DI-pointed words.  We can afford
  259. ;   to rewrite the entire screen on each refresh; so no special action needs to
  260. ;   be taken.  We do complicated looping to make the routine as fast as
  261. ;   possible.
  262.  
  263. MONO_COPY:
  264.   SHR CX,1        ; is the character count odd?
  265.   JC >L5        ; jump if yes, to special code
  266. L1:
  267.   SHR CX,1        ; is the character count a multiple of 4?
  268.   JC >L6        ; jump if not, to special code
  269. L2:            ; loop here to copy every 4 bytes
  270.   LODSB         ; load the character from the source
  271.   STOSW         ; output the character, with the standard attribute byte
  272.   LODSB         ; char # 2
  273.   STOSW
  274.   LODSB         ; char # 3
  275.   STOSW
  276.   LODSB         ; char # 4
  277.   STOSW
  278.   LOOP L2        ; loop for the next 4 characters
  279.   RET
  280.  
  281. L5:            ; the character count was odd
  282.   MOVSB         ; copy the odd character to the video buffer
  283.   INC DI        ; advance beyond the attribute byte
  284.   JCXZ RET        ; return if count is depleted
  285.   JMP L1        ; join even code
  286.  
  287. L6:            ; the character count is 2 mod 4
  288.   LODSB         ; load one character
  289.   STOSW         ; output it and the attribute-- count now 1 mod 4
  290.   LODSB         ; load second character
  291.   STOSW         ; output it-- count now 0 mod 4
  292.   JCXZ RET        ; return if count is depleted
  293.   JMP L2        ; join multiple-of-4 code
  294.  
  295.  
  296. ; COLOR_COPY is the VID_COPY routine for an IBM Color Graphics Adapter board.
  297. ;   The characters occupy the lower byte of the DI-pointed words. We must wait
  298. ;   for vertical retrace to output our data, to avoid annying "snow" on the
  299. ;   screen.  So we can't afford to output the entire buffer every time.  So we
  300. ;   maintain at [SI+81] a copy of what's already on the screen for [SI], and we
  301. ;   output only if the buffer is new.
  302.  
  303. COLOR_COPY:
  304.   PUSH BX        ; preserve BX across the call
  305.   MOV DX,03DA        ; load the port number for reading the video status
  306.   SKIP2         ; skip to the LODSB instruction
  307. L0:            ; loop here for every character that is already out there
  308.   INC DI        ; advance the output pointer beyond the character
  309. L1:            ; loop here after a non-matching character was stored
  310.   INC DI        ; advance beyond the following attribute byte
  311.   LODSB         ; fetch the next character
  312.   MOV BL,AL        ; save the character in BL
  313.   XCHG AL,[SI+79]   ; swap it with the already-out-there value
  314.   CMP AL,BL        ; is the character already out there?
  315.   LOOPE L0        ; loop if it is
  316.   JE >L4        ; jump if the characters are exhausted
  317. L2:            ; loop here to wait for vertical retrace
  318.   IN AL,DX        ; input the status
  319.   TEST AL,1        ; mask the retrace bit
  320.   JZ L2         ; loop if we are not in vertical retrace
  321.   MOV AL,BL        ; re-fetch the character to be output
  322.   STOSB         ; output the character
  323.   INC CX            ; undo the previous LOOPE's decrement of CX
  324.   LOOP L1        ; loop to check for another output character
  325.   INC DI        ; advance beyond the attribute byte of the last character
  326.   POP BX        ; restore clobbered register
  327.   RET
  328.  
  329. L4:            ; matching character was the last in the buffer
  330.   INC DI,2        ; advance beyond the output video word
  331.   POP BX        ; restore clobbered register
  332.   RET
  333.  
  334.  
  335. ; IBM_ATTR is the VID_ATTR routine for IBM-PC compatible computers.  The
  336. ;   attribute byte is the high byte of the DI-pointed video word.
  337.  
  338. IBM_ATTR:
  339.   INC DI        ; advance to the high, attribute byte
  340.   STOSB         ; output the attribute code AL to the byte
  341.   RET
  342.  
  343.  
  344. ; IBM_KEY is the BIOS_KEY routine for IBM_PC compatible computers.  We must
  345. ;   transform the two-byte code returned by the IBM BIOS into the single
  346. ;   code AL expected by the rest of the debugger.
  347.  
  348. IBM_KEY:
  349.   MOV AH,0        ; function code for GET KEY
  350.   INT 016        ; get the keystroke from the IBM BIOS
  351.   TEST AL        ; is the return AL nonzero?
  352.   JNZ RET        ; if yes then AL is our return code
  353.   MOV AL,AH        ; AL is zero, so AH determines the return code
  354.   ADD AL,080-16     ; shift the values into a range not seen directly in AL
  355.   RET
  356.  
  357.  
  358. ; IBM_BELL is the BIOS_BELL routine for IBM-PC compatible computers.  We
  359. ;   output the code 07 to the BIOS's console output routine.
  360.  
  361. IBM_BELL:
  362.   MOV AX,0E07       ; AH= console out function number; AL="BELL" control code
  363.   INT 010        ; output BELL to the console
  364.   RET
  365.  
  366.  
  367. ; NEW_KEYS reassigns the keyboard codes and the action routines for a non-
  368. ;   IBM-compatible BIOS.  We are called with CS:SI pointing to a table of
  369. ;   various new values, whose format is identical to the one given by
  370. ;   WANG_KEYS below.  The new values are plugged into the various tables
  371. ;   in the debugger, so that correct actions are taken for the non-compatible
  372. ;   machine.
  373.  
  374. NEW_KEYS:
  375.   PUSH DS        ; preserve DS across call
  376.   MOV DS,CS        ; point DS to our program, to read the table at SI
  377.   MOV ES,CS        ; also point the destination segment to our program
  378.   LODSB         ; load the first byte of the table
  379.   MOV HELP_KEY,AL    ; first byte is the code for HELP_KEY
  380.   LODSB         ; load the second byte
  381.   ADD SWITCH_KEY,AL    ; byte 2 is (new-IBM) function-key-codes-difference
  382.   MOV DI,CTRL_JUMPS+2    ; point to the control-jumps table
  383.   MOV CX,N_FUNCS    ; load the number of function-keys in that table
  384. L1:            ; loop here to adjust each function-key code
  385.   ADD [DI],AL        ; add the code into the table entry
  386.   ADD DI,3        ; advance to the next table entry
  387.   LOOP L1        ; loop to adjust the next table entry
  388.   MOV CL,N_CONTROL_KEYS ; load the number of subsequent keys in the table
  389. L2:            ; loop here to plug in the new value for each key
  390.   MOVSB         ; copy the new key code to the function table
  391.   INC DI,2        ; advance output pointer to the next key code
  392.   LOOP L2        ; loop to plug in the next key code
  393.   LODSW         ; fetch the message-pointer to the name of HELP key
  394.   MOV HELP_MSG,AX    ; plug the pointer into the messages-string
  395.   MOV DI,BIOS_CALLS    ; point to the table of action routines
  396.   MOV CX,N_BIOS_CALLS    ; load the count of words in action-routine-table
  397.   REP MOVSW        ; copy the new pointers to the table
  398.   POP DS        ; restore clobbered register
  399.   RET
  400.  
  401.  
  402.  
  403. ;------------------
  404. ;  WANG INTERFACE
  405. ;------------------
  406.  
  407. ; Thanks to Alan Tschetter for providing the information necessary for me
  408. ;   to program this interface.
  409.  
  410. WANG_KEYS:
  411.   DB 0E1           ; HELP key value
  412.   DB 07F-FUNC           ; add-quantity for FUNC
  413. L1:
  414.   DB 0C2,0C9,0C0,0C8,0C4 ; DOWN, NEXT, UP, PREV, HOME
  415.   DB 097,097           ; shift-F7 key, disabled Alt-F9 key
  416. N_CONTROL_KEYS EQU $-L1
  417.  
  418.   DW HELP_HELP      ; pointer to "HELP" message, the name of Wang's HELP key
  419.  
  420. L2:
  421.   DW WANG_COPY        ; VID_COPY routine
  422.   DW WANG_ATTR        ; VID_ATTR routine
  423.   DW RET        ; there is no VID_FIX necessary on the Wang
  424.   DW WANG_BELL        ; BIOS_BELL routine
  425.   DW WANG_KEY        ; BIOS_KEY routine
  426.   DW RET
  427.   DW RET
  428.   DW 0F000        ; new value for VIDEO_SEG
  429.   DB 0            ; normal-video attribute for the Wang PC
  430.   DB 2            ; reverse-video attribute for the Wang PC
  431. N_BIOS_CALLS EQU ($-L2)/2
  432.  
  433.  
  434. ; Other Wang keycodes:    F1--F16  80--8F
  435. ;            Prev     C8      Erase   CB
  436. ;            Insert     C6      Delete  C7
  437. ;            <---     C3      --->      C1
  438. ;            EXEC     C5
  439. ;   All the above codes add 010 for SHIFT versions.
  440. ;   NO ALT KEY!!!
  441. ;            Print     E3      Back Tab     CD
  442. ;            Cancel     E0      Shift Cancel 03
  443.  
  444.  
  445. ; WANG_CONFIG is the BIOS initialization routine for a Wang PC.  We copy the
  446. ;   values of WANG_KEYS to various locations, then we fetch the value of
  447. ;   ENABLE_PORT, that lets us access Wang's video memory, then we move the
  448. ;   user's cursor to the lower left corner.
  449.  
  450. L1:            ; console codes to move cursor to lower left corner
  451.   DB 01B,'[25;1H'       ; row 25, column 1
  452. L2 EQU $-L1        ; L2 is the count of bytes
  453.  
  454. WANG_CONFIG:
  455.   MOV SI,WANG_KEYS      ; point to Wang's table of key codes and other values
  456.   CALL NEW_KEYS         ; plug the new values into our program's data structures
  457.   MOV AL,1        ; function code for GET BIOS ENVIRONMENT
  458.   INT 088               ; sets ES to a segment where we'll find port #
  459.   ES MOV BX,[BX+10]    ; fetch a pointer
  460.   ES MOV AH,[BX+19]    ; use the pointer to fetch the high of the port #
  461.   MOV AL,010        ; low of the port # is always 010
  462.   MOV ENABLE_PORT,AX    ; store the port number
  463.   MOV DS,CS        ; point DS to our program, for console sequence
  464.   MOV DX,L1             ; point DX to the "go to lower left" console sequence
  465.   MOV CX,L2        ; load the number of bytes in the sequence
  466.   MOV BH,0              ; device number, maybe?  I don't know for sure
  467.   MOV AL,0D             ; function number, maybe?  I don't know for sure
  468.   INT 088               ; output escape string, user's cursor goes to lower left
  469.   RET
  470.  
  471.  
  472. ; WANG_COPY is the Wang-PC version of the VID_COPY routine.  The character
  473. ;   and attribute bytes are reversed from what they are on the IBM-PC, so
  474. ;   AH and AL are swapped before and after every word output.  There are no
  475. ;   snow problems; so we can get away with copying everything every time.
  476. ;   We do need to enable the video memory, though.
  477.  
  478. WANG_COPY:
  479.   MOV DX,ENABLE_PORT  ; fetch the port number for enabling video memory
  480.   MOV AL,1          ; value 1 causes memory to be enabled
  481.   OUT DX,AL          ; we can now access the video memory
  482. L1:              ; loop here for each character to be copied
  483.   LODSB           ; fetch the next character
  484.   XCHG AH,AL          ; swap character into AH, attribute byte into AL
  485.   STOSW           ; output the word to video memory
  486.   MOV AH,AL          ; copy the attribute byte back to AH, for next char
  487.   LOOP L1          ; loop to copy the next character
  488. L2:              ; common exit with WANG_ATTR
  489.   MOV AL,0          ; value 0 shuts off access to video memory
  490.   OUT DX,AL          ; video access is now disabled
  491.   RET
  492.  
  493.  
  494. ; WANG_ATTR is the Wang-PC version of the VID_ATTR routine.  The attribute
  495. ;    byte is the low byte of the DI-pointed video memory.  Also, to access it,
  496. ;    we must send the code that enables Wang video memory.
  497.  
  498. WANG_ATTR:
  499.   PUSH AX          ; preserve the attribute code
  500.   MOV DX,ENABLE_PORT  ; fetch the port number for enabling video memory
  501.   MOV AL,1          ; value 1 causes memory to be enabled
  502.   OUT DX,AL          ; we can now access the video memory
  503.   POP AX          ; restore the attribute code
  504.   STOSB           ; output the attribute byte to the LOW byte of video word
  505.   JMP L2          ; join common code to disable video access
  506.  
  507.  
  508. ; WANG_KEY is the Wang-PC version of the BIOS_KEY routine.
  509.  
  510. WANG_KEY:
  511.   PUSH BX          ; preserve register across call
  512. L1:              ; loop here to wait for a key to become ready
  513.   MOV AL,15          ; Wang BIOS function code for GET KEY STATUS
  514.   MOV BL,2            ; another parameter for Wang BIOS - I'm not sure which
  515.   INT 088          ; call Wang BIOS to get the status and maybe the key
  516.   TEST AL          ; do we have a key?
  517.   JNZ L1          ; loop if not, to try again
  518.   XCHG AX,BX          ; we do: swap the key code into AL for return
  519.   POP BX          ; restore clobbered register
  520.   RET
  521.  
  522.  
  523. ; WANG_BELL is the Wang-PC version of the BIOS_BELL routine.
  524.  
  525. WANG_BELL:
  526.   MOV BX,7          ; BL=7 is the BELL code; the BIOS also wants BH=0
  527.   MOV AL,6          ; Wang BIOS function code for CONSOLE OUTPUT
  528.   INT 088          ; output the BELL control code to the Wang console
  529.   RET
  530.  
  531.  
  532. ;------------------
  533. ;  TI-PC INTERFACE
  534. ;------------------
  535.  
  536. ; Thanks to David R. Cook for writing the following code.  I have reformatted
  537. ; it to look like the rest of my code, and made optimizations.
  538.  
  539. TIPC_KEYS:
  540.   DB 0B5       ; key code for F11 - the help key
  541.   DB 0AA-FUNC       ; F1 is code 0AB on the TI-PC
  542. L1:
  543.   DB 0C0       ; down-arrow key
  544.   DB 0C1       ; no PgDn key on the TI-PC, so we use alt-down-arrow code
  545.   DB 0B8       ; up-arrow key
  546.   DB 0B9       ; no PgUp key on the TI-PC, so we use alt-up-arrow code
  547.   DB 0B7       ; HOME key
  548.   DB 0CA       ; shift-F7 key
  549.   DB 0E0       ; alt-F9 key
  550. N_CONTROL_KEYS equ $-L1
  551.  
  552.   DW F11_HELP       ; pointer to help message
  553.  
  554. L2:
  555.   DW TIPC_COPY        ; VID_COPY routine
  556.   DW TIPC_ATTR        ; VID_ATTR routine
  557.   DW TIPC_FIX        ; VID_FIX routine
  558.   DW TIPC_BELL        ; BIOS_BELL routine
  559.   DW TIPC_KEY        ; BIOS_KEY routine
  560.   DW RET
  561.   DW RET
  562.   DW 0DE00        ; new value for VIDEO_SEG
  563.   DB 0F         ; normal-video attribute for the TI-PC
  564.   DB 01F        ; reverse-video attribute for the TI-PC
  565. N_BIOS_CALLS equ ($-L2)/2
  566.  
  567. ; Other TI keycodes:
  568.  
  569. ;   key   +shift  +alt      +ctrl  plain
  570. ;   ----------------------------------
  571. ;   F1      0C4      0D8      0CE     0AB
  572. ;   ...
  573. ;   F10   0CD      0E1      0D7     0B4
  574. ;   F11   "x"     "|"     "z"    0B5
  575. ;   F12   "y"     "}"     "{"    0B6
  576. ;
  577. ;   PRNT             0E2
  578. ;   INS   098      09A      099     0C2
  579. ;   DEL   0A8      0AA      0A9     0C3
  580. ;   UP AR 0F8      0B9      0F4
  581. ;   DN AR 0F9      0C1      0E6
  582. ;   LT AR 0FB      0BC      0E3     0BB
  583. ;   RT AR 0FA      0BE      0E4     0BD
  584. ;   HOME  0F6      0F5      0E7
  585. ;   TAB   07F    ignored ignored   09
  586.  
  587.  
  588.  
  589. ; TIPC_CONFIG is the BIOS initialization routine for the TI-PC.  We copy the
  590. ;   values in TIPC_KEYS to various locations, then we drop into TIPC_FIX,
  591. ;   to reset the cursor.
  592.  
  593. TIPC_CONFIG:
  594.   MOV SI,TIPC_KEYS      ; point to configuration-table for TI-PC's BIOS
  595.   CALL NEW_KEYS     ; copy the values to our tables
  596. TIPC_FIX:
  597.   MOV AH,014            ; BIOS function code for "clear graphics screen"
  598.   INT 049        ; clear the graphics screen
  599.   MOV AH,013            ; BIOS function code for "clear text screen"
  600.   INT 049        ; clear the text screen
  601.   MOV AH,2              ; BIOS function code for "position the cursor"
  602.   MOV DX,1 BY 24    ; first column, 24th row
  603.   INT 049               ; move the user's cursor to the bottom left corner
  604.   RET
  605.  
  606.  
  607. ; TIPC_COPY is the VID_COPY routine for the TIPC video board.  The attribute
  608. ;   AH is written to a single memory-mapped latch in the video segment.
  609. ;   Then the text bytes can be copied as-is.
  610.  
  611. TIPC_COPY:
  612.   ES MOV B[01801],AH    ; set the attribute latch
  613.   SHR DI,1        ; adjust the video address for bytes, not words
  614.   REP MOVSB        ; copy the text as-is
  615.   SHL DI,1        ; restore the video address to words, not bytes
  616.   RET
  617.  
  618.  
  619. ; TIPC_ATTR is the VID_ATTR routine for TI-PC computer.  We change the
  620. ;   attribute latch to the one provided in AL, then we add 0 to the video
  621. ;   character in memory, causing the new latch value to take effect.
  622.  
  623. TIPC_ATTR:
  624.   SHR DI,1        ; adjust video address for bytes, not words
  625.   ES MOV AH,B[DI]    ; fetch the character
  626.   ES MOV B[01801],AL    ; rewrite the latch with the caller's value
  627.   ES MOV B[DI],AH    ; re-write the value already there, to effect the latch
  628.   SHL DI,1        ; restore DI
  629.   RET
  630.  
  631.  
  632. ; TIPC_KEY is the BIOS_KEY routine for TI_PC computer.    We must transform the
  633. ;   two-byte code returned by the TIPC BIOS into the single code AL expected by
  634. ;   the rest of the debugger. The only differences to IBM_KEY are the interrupt
  635. ;   number, and the mapping of the codes received and returned.
  636.  
  637. TIPC_KEY:
  638.   MOV AH,0        ; function code for GET KEY
  639.   INT 04A        ; get the keystroke from the TIPC BIOS
  640.   TEST AL        ; is the return AL nonzero?
  641.   JNZ RET        ; if yes then AL is our return code
  642.   MOV AL,AH        ; AL is zero, so AH determines the return code
  643.   ADD AL,080-16     ; shift the values into a range not seen directly in AL
  644.   RET
  645.  
  646.  
  647. ; TIPC_BELL is the BIOS_BELL routine for TIPC-PC computer.  We output the code
  648. ;   07 to the BIOS's console output routine. The only difference to IBM_KEY is
  649. ;   the interrupt number.
  650.  
  651. TIPC_BELL:
  652.   MOV AX,0E07       ; AH= console out function number; AL="BELL" control code
  653.   INT 049        ; output BELL to the console
  654.   RET
  655.  
  656.  
  657. ;------------------
  658. ; SANYO INTERFACE
  659. ;------------------
  660.  
  661. ; Thanks to Jerry Farnsworth for providing the information necessary for me
  662. ;   to program this interface.
  663.  
  664. SANYO_KEYS:
  665.   DB 0DC       ; key code for Ctrl-PF5 -- the help key
  666.   DB 0           ; same function codes as IBM-PC
  667. L1:
  668.   DB 0C0       ; down-arrow key
  669.   DB 0C1       ; PgDn key
  670.   DB 0B8       ; up-arrow key
  671.   DB 0B9       ; PgUp key
  672.   DB 0B7       ; HOME key
  673.   DB 0CA       ; shift-F7 key is Ctrl 7 on the Sanyo
  674.   DB ALT_F 9       ; Ctrl-Shift-PF4 will restore a trashed screen
  675. N_CONTROL_KEYS equ $-L1
  676.  
  677.   DW PF5_HELP       ; pointer to help message
  678.  
  679. L2:
  680.   DW SANYO_COPY     ; VID_COPY routine
  681.   DW SANYO_ATTR     ; VID_ATTR routine
  682.   DW SANYO_FIX        ; VID_FIX routine
  683.   DW IBM_BELL        ; BIOS_BELL routine
  684.   DW IBM_KEY        ; BIOS_KEY routine
  685.   DW SANYO_SAVE     ; we must save the BIOS cursor position
  686.   DW SANYO_RESTORE  ; we must restore the BIOS cursor position
  687.   DW 07C00        ; new value for VIDEO_SEG
  688.   DB 07         ; normal-video attribute for the Sanyo-PC
  689.   DB 0F0        ; reverse-video attribute for the Sanyo-PC
  690. N_BIOS_CALLS equ ($-L2)/2
  691.  
  692.  
  693. ; Other Sanyo keycodes:
  694.  
  695. ; IBM         Sanyo           IBM          Sanyo
  696.  
  697. ; Alt         Ctrl Shift        DOWN       numeric pad 5
  698. ; Alt Fn     Ctrl Fn           END          numeric pad 2
  699. ; Shift Fn   Ctrl n
  700. ; Ctrl 2     Ctrl `                Ctrl F12345    Ctrl ={}:"
  701. ; Ctrl 6     Ctrl tilde            Ctrl F678910   Ctrl ;',./
  702.  
  703.  
  704.  
  705. ; SANYO_CONFIG is the BIOS initialization routine for a Sanyo 55x.  We copy the
  706. ;   values of SANYO_KEYS to various locations, fetch and store the current
  707. ;   video page, and set the user cursor to the lower left of the screen.
  708.  
  709. ; SANYO_FIX insures a screen refresh by filling the "actual" buffers of SCREEN_P
  710. ;   with impossible FF-values.
  711.  
  712. SANYO_CONFIG:
  713.   MOV SI,SANYO_KEYS     ; point to configuration-table for SANYO's BIOS
  714.   CALL NEW_KEYS     ; copy the values to our tables
  715.   MOV AH,15        ; function number for fetching the video page
  716.   INT 010        ; set BH to the current video page
  717.   CS MOV SANYO_PAGE,BH    ; store the page throughout the debugging session
  718.   MOV DX,24 BY 0    ; load coordinates for the lower left corner
  719.   CALL SET_SANYO_POS    ; store this position
  720.   CALL SANYO_RESTORE    ; this call causes the user cursor to move there
  721. SANYO_FIX:
  722. NO_ACTUAL:
  723.   MOV AX,0FFFF        ; load AH and AL with the 0FF impossible-value
  724. FILL_ACTUAL:
  725.   MOV ES,SS        ; destination segment is our stack, for buffer-fill
  726.   MOV DI,SCREEN_P+80    ; point to the actual-buffer for the first line
  727.   MOV DL,24        ; load the count of actual lines to fill
  728. L2:
  729.   MOV CX,40        ; number of words in the actual buffer
  730.   REP STOSW        ; fill the buffer with the words
  731.   ADD DI,256-80         ; advance output pointer to the next line's actual buff.
  732.   DEC DL        ; count down lines
  733.   JNZ L2        ; loop to fill the next line
  734.   RET
  735.  
  736.  
  737. ; SANYO_COPY is the VID_COPY routine for the Sanyo.  The Sanyo does not have
  738. ;   a hardware character generator, so we call the BIOS to copy bit-patterns
  739. ;   to the screen.
  740.  
  741. SANYO_COPY:
  742.   MOV AX,DI        ; fetch the output character number
  743.   ADD DI,CX        ; add the character count
  744.   ADD DI,CX        ; add it twice, to advance by words not bytes
  745.   PUSH BX,DI            ; preserve caller's BX and return DI value
  746.   MOV BH,0        ; load the page number
  747. SANYO_PAGE EQU B[$-1]    ; previous immediate value is plugged in
  748.   CALL GET_ROWCOL    ; convert character number AX into row-and-column DX
  749.   DEC DX        ; cancel the following first INC DX
  750. L1:            ; loop here for every character already out there
  751.   INC DX        ; advance the column number DL to the next position
  752.   LODSB         ; fetch the next character
  753.   MOV BL,AL        ; save the character in BL
  754.   XCHG AL,[SI+79]    ; swap it with the already-out-there value
  755.   CMP AL,BL        ; is the character already out there?
  756.   LOOPE L1        ; loop if it is
  757.   JE >L2        ; jump if the characters are exhausted
  758.   INC CX                ; undo the previous LOOPE's decrement of CX
  759.   CALL SET_IBM_CURSOR    ; move the cursor to the indicated position
  760.   MOV AL,BL        ; fetch the character to be output
  761.   MOV BL,7              ; load the attribute code, always 7 in Sanyo's case
  762.   PUSH CX        ; save the character count
  763.   MOV CX,1        ; we are outputting 1 character in this call
  764.   MOV AH,9        ; BIOS function number for WRITE_CHAR
  765.   INT 010        ; write the character to the screen
  766.   POP CX        ; restore the character count
  767.   LOOP L1        ; loop to check for another output character
  768. L2:
  769.   POP DI,BX        ; restore clobbered registers
  770.   RET
  771.  
  772.  
  773. ; SANYO_ATTR is the VID_ATTR routine for the Sanyo.  We use the BIOS to
  774. ;   move the cursor to the current position, read the character that is
  775. ;   already there, and rewrite the character with the new attribute.
  776.  
  777. SANYO_ATTR:
  778.   PUSH BX,CX,DX,DI    ; save registers across call
  779.   PUSH AX        ; save the attribute across the repositioning
  780.   MOV AX,DI        ; fetch the character number
  781.   CALL GET_ROWCOL    ; convert the character number AX to row-and-column DX
  782.   CS MOV BH,SANYO_PAGE    ; load the current page number
  783.   CALL SET_IBM_CURSOR    ; move the cursor to the required location
  784.   MOV AH,8        ; function number for READ_CHARACTER
  785.   INT 010        ; set AL to the character already there
  786.   POP DX        ; restore DL = new attribute byte
  787.   MOV BL,DL        ; copy the attribute to BL where the BIOS expects it
  788.   MOV CX,1        ; we are writing one character only
  789.   MOV AH,9        ; BIOS function number for WRITE_CHAR
  790.   INT 010        ; write the character to the screen
  791.   POP DI,DX,CX,BX    ; restore clobbered registers
  792.   RET
  793.  
  794.  
  795. ; GET_ROWCOL an address AX into a row number DH and column number DL.  The input
  796. ;   AX address is twice the number of characters from the start of the screen
  797. ;   to the current cursor position.
  798.  
  799. GET_ROWCOL:
  800.   MOV DI,160        ; each line advances the address by 160
  801.   SUB DX,DX        ; the upper word of the dividend DXAX is always 0
  802.   DIV DI        ; convert the address to row AX, column DL*2
  803.   MOV DH,AL        ; the row is returned in DH
  804.   SHR DL,1        ; the column is returned in DL
  805.   RET
  806.  
  807.  
  808. ; SANYO_SAVE is the BIOS_SAVE routine for the Sanyo.  We record the user's
  809. ;   cursor position, so that it can be restored by BIOS_RESTORE.
  810.  
  811. SANYO_SAVE:
  812.   MOV AH,3        ; BIOS function number for READ_CURSOR_POSITION
  813.   INT 010        ; set DX to the current user cursor position
  814. SET_SANYO_POS:
  815.   CS MOV SANYO_POS,DX    ; store the cursor position DX
  816.   RET
  817.  
  818.  
  819. ; SANYO_RESTORE is the BIOS_RESTORE routine for the Sanyo.  We set the
  820. ;   user's sursor position to the place previously stored.
  821.  
  822. SANYO_RESTORE:
  823.   MOV DX,0        ; fetch the cursor position
  824. SANYO_POS EQU W[$-2]    ; the above immedaite operand has been plugged
  825.   JMP SET_IBM_CURSOR    ; jump to set the user's cursor
  826.  
  827.  
  828. ;------------------------
  829. ;  TANDY 2000 INTERFACE
  830. ;------------------------
  831.  
  832. ; Thanks to John B. Harrell, Contributing Editor PC Resuorce, for writing
  833. ;    the following code.  I have made minor code optimizations.
  834.  
  835. TANDY_KEYS:
  836.   DB ALT_F 10        ; code for Alt-F10 -- the HELP key
  837.   DB 0            ; F1 code same as on IBM-PC
  838. L1:
  839.   DB 0C0        ; Down Arrow
  840.   DB 0C1        ; PgDn
  841.   DB 0B8        ; Up Arrow
  842.   DB 0B9        ; PgUp
  843.   DB 0B7        ; Home
  844.   DB 0CA        ; Shift F7
  845.   DB ALT_F 9        ; Alt-F9 fixes a trashed screen
  846. N_CONTROL_KEYS EQU $-L1
  847.  
  848.   DW ALTF10_HELP    ; pointer to help message
  849.  
  850. L2:
  851.   DW MONO_COPY        ; VID_COPY routine
  852.   DW IBM_ATTR        ; VID_ATTR routine
  853.   DW TANDY_FIX        ; VID_FIX routine
  854.   DW IBM_BELL        ; BIOS_BELL routine
  855.   DW IBM_KEY        ; BIOS_KEY routine
  856.   DW RET        ; BIOS_SAVE routine needed for Sanyo only
  857.   DW RET        ; BIOS_RESTORE routine needed for Sanyo only
  858. TANDY_VSEG  DW ?    ; Tandy 2000 floating video segment address = VIDEO_SEG
  859.   DB 0A         ; normal video attribute on Tandy 2000
  860.   DB 0CA        ; reverse video attribute on Tandy 2000
  861. N_BIOS_CALLS EQU ($-L2)/2
  862.  
  863. ; Other Tandy 2000 keycodes:
  864.  
  865. ;   key   +shift  +alt      +ctrl  plain
  866. ;   ----------------------------------
  867. ;   F1      0C4      0D8      0CE     0AB
  868. ;   ...
  869. ;   F10   0CD      0E1      0D7     0B4
  870. ;   F11   012     "&"     01C    008
  871. ;   F12   013     "`"     01D    009
  872. ;
  873. ;   PRNT  ---      0B6      0E2     010
  874. ;   INS   0F9      010      00F     0C2
  875. ;   DEL   0FA      00E      00D     0C3
  876. ;   UP AR 0F5      001      000
  877. ;   DN AR 0F6      007      006
  878. ;   LT AR 0F7      002      0E3     0BB
  879. ;   RT AR 0F8      ---      0E4     0BD
  880. ;   HOME  0BA      016      0E7
  881. ;   TAB   07F      0FE      0FD     009
  882. ;   BKSP  008      0FC      07F     008
  883. ;   TAB   07F      0FE      0FD     009
  884. ;   ESC   01B      0FB      01B     01B
  885. ;   END   ---      ---      0E5     0BF
  886. ;   PGUP  ---      ---      0F4     0B9
  887. ;   PGDN  ---      ---      0E6
  888.  
  889. TANDY_CONFIG:
  890.   INT 012           ; get reported memory size in KBytes
  891.   MOV CL,6           ; shift count = * 64 for Kbytes to paragraphs
  892.   SHL AX,CL           ; convert to paragraphs
  893.   ADD AX,0080           ; point to starting location of monochrome video buffer
  894.   CS MOV TANDY_VSEG,AX ; save in data structure
  895.   MOV SI,TANDY_KEYS    ; point to configuration table for Tandy 2000
  896.   CALL NEW_KEYS        ; copy the value into BIOS tables
  897. TANDY_FIX:
  898.   MOV AX,0 BY 2        ; AH= BIOS function code for SET_VIDEO_MODE; AL = mode 0
  899.   INT 16           ; force a monochrome video mode
  900.   JMP SET_IBM_LOW_LEFT ; move the cursor to the lower left corner
  901.